/*
PARI/GP scripts for Blazys expansions and fractions 
=============================================================
File: BlazysExpansions.txt    
Link: https://oeis.org/wiki/File:BlazysExpansions.txt
=============================================================
Last updated 4 Nov 2014.
Reference:
Sykora S., Blazys Expansions and Continued Fractions,
http://dx.doi.org/10.3247/sl4math13.001. 
*/


Bx(x,nmax) =
/* ----------------------------------------------------------
  Implements the Blazys expansion of an irrational number x
  into a non-decreasing sequence of natural numbers (a vector).
  The desired size of the output vector is nmax.
  Use your judgement and take care of the following issues:
  - Do not input integer or rational numbers or irrational
  numbers smaller than 1 because they are sure to generate
  a run-time error (division by zero).
  - The input value x must have sufficient precision to
  make sure that all the elements of the output are correct.
  Try, for example, to double the precision and check whether
  all the the desired terms remain invariant. Typically, the
  recommended starting precision is at least 100 times
  more digits than nmax!
  - If you get nevertheless an error of the type
  "insufficient precision in truncation (floor)", the input
  value x probably has an excellent rational approximation.
  The problem can be usually removed by increasing the
  precision. Some exceptional numbers require really huge
  precision. For example, the value 2*Euler took a precision
  of 100000 digits to compute correctly element v[494].
  Test:
  1/(exp(1)-2) generates the sequence of natural numbers.
  Used to generate A233582 to A233587.
---------------------------------------------------------- */
{
  my(c = x,v = vector(nmax));
  for(k=1,nmax, v[k] = floor(c); c = v[k]/(c-v[k])); 
  return (v);
}

Ebx(x,nmax) = RunningSumInverse(Bx(x+1.0,nmax));
/* ----------------------------------------------------------
  Implements the extended ebx(x) expansion
---------------------------------------------------------- */

Bf(v) =
/* ----------------------------------------------------------
  Evaluates the Blazy's continued fraction, i.e., the inverse
  of the Blazys expansion of a non-decreasing sequence v
  of natural numbers (a vector) into a real number. 
  Use your judgement to make sure that the input vector has
  a sufficient number of terms to guarantee the correctness
  of the result. Play with it, for example doubling the size
  of v and checking how many digits of the result remain
  invariant. The convergence is quite fast (the error drops
  by about 1/(1+a(k)) with every term a(k), so it should not
  be a big problem.
  Test:
  The sequence of natural numbers expands into 1/(exp(1)-2).
  Used to generate A233588 to A233591 and check on A194807.
---------------------------------------------------------- */
{
  my(am=1.0,a=0.0+v[1],bm=0.0,b=1.0,n=1,f=a,flast=f,aux);
  while (n<100,
    aux = v[n+1]*a + v[n]*am;
    am = a; a = aux;
    aux = v[n+1]*b + v[n]*bm;
    bm = b; b = aux;
    flast = f;
    f = a/b;
    n++;
  );
  return(f);
}

Ebf(v) = Bf(RunningSumInverse(v))-1.0;
/* ----------------------------------------------------------
  Implements extended ebf(v) mapping
---------------------------------------------------------- */

BxPeriodicSqrtN(nmax) =
/* ----------------------------------------------------------
  Lists numbers n for which bx(sqrt(n)) is periodic.
  Used to generate A233592.
---------------------------------------------------------- */
{
  my (k=0,n=0,v=vector(nmax),s);
  while (n<nmax, k++;
    if (!issquare(k), s=Bx(sqrt(k),100);
      if (s[100]==s[99], n++;v[n]=k;print(k," ",s[1..10])); 
    );
  );
  return (v);
}

BxAperiodicSqrtN(nmax) =
/* ----------------------------------------------------------
  Lists the numbers n for which bx(sqrt(n)) is a-periodic.
  Used to generate A233593.
---------------------------------------------------------- */
{
  my (k=0,n=0,v=vector(nmax),s);
  while (n<nmax, k++;
    if (!issquare(k), s=Bx(sqrt(k),100);
      if (s[100]!=s[99], n++;v[n] = k;print(k," ",s[1..10])); 
    );
  );
  return (v);
}


/*
=============================================================
   Contributed to OEIS Wiki by Stanislav Sykora
=============================================================
*/
